package com.yilin.platform.controller.system;

import com.yilin.platform.base_core.application.BaseController;
import com.yilin.platform.base_core.application.ReturnData;
import com.yilin.platform.base_core.commons.annotation.Explain;
import com.yilin.platform.base_core.commons.annotation.SafeVerify;
import com.yilin.platform.base_core.commons.annotation.UserTarget;
import com.yilin.platform.base_core.commons.utils.ArrayUtil;
import com.yilin.platform.base_core.commons.utils.FieldUtil;
import com.yilin.platform.base_core.commons.utils.MapUtil;
import com.yilin.platform.base_core.components.redis.RedisClient;
import com.yilin.platform.base_core.components.redis.RedisKeys;
import com.yilin.platform.entity.enums.user.UserType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.xml.crypto.Data;
import java.lang.reflect.Field;
import java.util.*;

@RestController
@RequestMapping("/system/redis/")
public class RedisController extends BaseController {

    @PostMapping("getRedisStatsInfo")
    @UserTarget(UserType.adminUser)
    public ReturnData<Map<String, Object>> getRedisStatsInfo() {
        Map<String, Object> map = new HashMap<>();
        RedisClient instance = RedisClient.getInstance();
        Map<String, String> redisServer = instance.getRedisServer();
        Map<String, String> redisStats = instance.getRedisStats();
        Map<String, String> redisMemory = instance.getRedisMemory();
        List<String> redisKeys = instance.getAllKeys();
        Map<String, Object> statsInfo = MapUtil.generate(clientMap1 -> {
            clientMap1.put("redisVersion", redisServer.get("redis_version"));
            clientMap1.put("tcpPort", redisServer.get("tcp_port"));
            clientMap1.put("clientCount", instance.getClientCount());
            clientMap1.put("keysCount", redisKeys.size());
            clientMap1.put("expiredKeys", redisStats.get("expired_keys"));
            clientMap1.put("uptimeInDays", redisServer.get("uptime_in_days"));
            clientMap1.put("usedMemoryHuman", redisMemory.get("used_memory_human"));
        });
        map.put("statsInfo", new TreeMap<>(statsInfo));
        //----------------------------------------------
        List<Field> fields = FieldUtil.getFields(RedisKeys.class);
        List<Map<String, Object>> keyDataList = new ArrayList<>();
        for (String redisKey : redisKeys) {
            Map<String,Object> keyData = new HashMap<>();
            Field field = ArrayUtil.getBy(fields, obj -> obj.getName().equals(redisKey));
            keyData.put("keyName",redisKey);
            keyData.put("keyExplain",field==null?"无":field.getAnnotation(Explain.class).value());
            keyData.put("keyExpire", instance.getExpire(redisKey));
            keyData.put("keySize", instance.getSize(redisKey));
            keyData.put("keyValues", instance.hEntries(redisKey));
            keyDataList.add(keyData);
        }
        map.put("keyDataList", keyDataList);
        return jsonView(true, "获取REDIS信息成功", map);
    }

    @PostMapping("getRedisFactoryInfo")
    @UserTarget(UserType.adminUser)
    public ReturnData<Map<String, Object>> getRedisFactoryInfo() {
        Map<String, Object> map = new HashMap<>();
        map.put("server", RedisClient.getInstance().getRedisServer());
        map.put("clients", RedisClient.getInstance().getRedisClients());
        map.put("memory", RedisClient.getInstance().getRedisMemory());
        map.put("persistence", RedisClient.getInstance().getRedisPersistence());
        map.put("stats", RedisClient.getInstance().getRedisStats());
        map.put("replication", RedisClient.getInstance().getRedisReplication());
        map.put("cpu", RedisClient.getInstance().getRedisCpu());
        map.put("commandstats", RedisClient.getInstance().getRedisCommandstats());
        map.put("cluster", RedisClient.getInstance().getRedisCluster());
        map.put("keyspace", RedisClient.getInstance().getRedisKeyspace());
        return jsonView(true, "获取REDIS工厂信息成功", map);
    }

    @PostMapping("removeRedisKeys")
    @UserTarget(UserType.adminUser)
    @SafeVerify
    public ReturnData<Data> removeRedisKeys(String[] keys) {
        RedisClient.getInstance().delete(ArrayUtil.initList(keys));
        return jsonView(true, "操作成功");
    }

    @PostMapping("removeRedisKey")
    @UserTarget(UserType.adminUser)
    @SafeVerify
    public ReturnData<Data> removeRedisKey(String key) {
        RedisClient.getInstance().delete(key);
        return jsonView(true, "操作成功");
    }

    @PostMapping("removeRedisKeyField")
    @UserTarget(UserType.adminUser)
    @SafeVerify
    public ReturnData<Data> removeRedisKeyField(String key, String field) {
        RedisClient.getInstance().hdel(key, field);
        return jsonView(true, "操作成功");
    }
}
